# -*- coding: utf8 -*-

'''
This module implements so-called "chapter files". They
are simple ini-files, similar like produced with musepack-tools,
the difference is that common tags (example 'Date','Author' etc.)
are listed in separate ini-section called [common_tags]. This
will make the manual editing a bit easier.
To avoid disturb, the new chapter files will be named *.chap

Licence: GPLv2
Author: Joseph Botosh <rumly111@gmail.com>
'''

import mpcchap
import configparser

class ChapterFileException(Exception):
    pass

class ChapterFileParser(mpcchap.MpcChapters):
    '''
    This class is a wrapper around MpcChapters class.
    The only function of it is to read/write chapter files.
    '''
    def __init__(self):
        mpcchap.MpcChapters.__init__(self)
        # self.common_tags = set()

    @property
    def common_tags(self) -> set:
        all_tag_values = dict()
        for ch in self.chapters:
            for tag_name in ch.keys():
                if tag_name in all_tag_values.keys():
                    all_tag_values[tag_name].add(ch[tag_name])
                else:
                    all_tag_values[tag_name] = {ch[tag_name]}

        ct = set()
        for tag_name in all_tag_values.keys():
            if len(all_tag_values[tag_name]) == 1:
                ct.add(tag_name)
            
        return ct

    @property
    def all_tags(self) -> set:
        result = set()
        for ch in self.chapters:
            ch_tags = set(tn for tn in ch.keys())
            result.update(ch_tags)
        return result

    @property
    def uniq_tags(self) -> set:
        ut = self.all_tags - self.common_tags
        return ut    
        
    def read_chap_file(self, source : str):
        '''
        Read tags from *.chap file.
        '''

        def apply_tags(name,value):
            for ch in self.chapters:
                ch[name]=value
        
        if not source.endswith('.chap'):
            raise ChapterFileException(
                  'Invalid chapter file name: {}'.format(source))
##        if not os.file.exists(source):
##            raise ChapterFileException(
##                  'Source file {} does not exist'.format(source))

        cp = configparser.ConfigParser()
        cp.optionxform = str
        try:
            cp.read(source)
        except configparser.Error:
            # TODO: be more informative
            raise ChapterFileException('Bad *.chap file')

        if not cp.has_section('common_tags'):
            raise ChapterFileException('No [common_tags] found')

        self.chapters = []
        self.start_samples = []

        for ss in cp.sections():
            if ss != 'common_tags':
                self.start_samples.append(ss)
                new_chapter = dict() # or should I use default_chapter ?
                for tag_name in cp.options(ss):
                    tag_value = cp.get(ss,tag_name).strip('"')
                    new_chapter[tag_name] = tag_value    
                self.chapters.append(new_chapter)

        # It is important to write common tags after uniq ones
        for common_tag_name in cp.options('common_tags'):
            common_tag_value = cp.get('common_tags',common_tag_name).strip('"')
            apply_tags(common_tag_name,common_tag_value)


    def write_chap_file(self, destination : str):
##        if not destination.endswith('.chap'):
##            raise ChapterFileException(
##                  'Invalid chapter file name: {}'.format(destination))

        if self.chapters == []:
            raise ChapterFileException('No chapters loaded')
        chap_file = open(destination,mode='wt')

        chap_file.write('[common_tags]\n')
        for tag_name in self.common_tags:
            tag_value = self.chapters[0][tag_name]
            chap_file.write('{0}="{1}"\n'.format(tag_name,tag_value))
        chap_file.write('\n')

        for song_num in range(len(self.chapters)):
            start_sample = self.start_samples[song_num]
            chapter = self.chapters[song_num]
            chap_file.write('[{}]\n'.format(start_sample))
            for tag_name in self.uniq_tags:
                try:
                    tag_value = chapter[tag_name]
                    chap_file.write('{0}="{1}"\n'.format(tag_name,tag_value))
                except KeyError:
                    pass
            chap_file.write('\n')
            
        chap_file.close()



##cfp = ChapterFileParser()
##cfp.read_chapters_from('/tmp/mpc/madonna.ini')
##cfp.write_chap_file('/tmp/mpc/madonna.chap')
##cfp.read_chap_file('/tmp/mpc/madonna.chap')
##cfp.write_chap_file('/tmp/mpc/madonna2.chap')
